var CGame = {
	CameraMode: 0,
	CameraFOV: 70,
	CameraFOVSpeed: 3,
	CameraDistanceSpeed: 3,
	FocusEntityVehicle: null
};

function OnScriptLoad() {
	Client.Camera.StartLookAt(Vector(25, 50, 25), Vector(0, 0, 0), 0.5);
	Client.Camera.SetCinematicBorder(true);

	Client.Camera.FOV = 1;

	Client.Core.LoadScript("Client/Client.Function.js");
	Client.Core.LoadScript("Client/Client.Account.js");

	Client.Core.BindNativeKey("World_CameraMode", "V");
	Client.Core.BindNativeKey("Vehicle_Horn", "H");
	Client.Core.BindNativeKey("Vehicle_Alarm", "X");
	Client.Core.BindNativeKey("Vehicle_Light", "L");
}

/**
 * @param {float} dt
 */
function OnFrameUpdate(dt) {

}

/**
 * @param {string} rpc
 * @param {any} arg0
 * @param {any} arg1
 * @param {any} arg2
 */
function OnServerNetworkRPC(rpc, arg0, arg1, arg2) {
	if (rpc == "account_panel_show") {
		CreateAccountPanel();
	} else if (rpc == "account_panel_hide") {
		DestroyAccountPanel();
	}
}

/**
 * @param {Client.Player} player
 * @param {Client.Character} entity
 */
function OnPlayerEntityLogin(player, entity) {
	if (player.IsLocal) {
		Client.Camera.StopLookAt();
		Client.Camera.Target = entity;

		Client.Camera.FOVSpeed = CGame.CameraFOVSpeed;
		Client.Camera.DistanceSpeed = CGame.CameraDistanceSpeed;

		UpdateCameraState(CGame.CameraMode);

		let startPos = Vector(entity.Pos.x + Random.Range(-10, 10), entity.Pos.y + 8, entity.Pos.z + Random.Range(-10, 10));
		Client.Camera.StartLookAt(startPos, entity.Pos, 3);

		Client.Timer.Create(() => {
			Client.Camera.StopLookAt();

			Client.Camera.SetCinematicBorder(false);

			Client.Backpack.SetHotbarActive(true);
			Client.GUI.SetCrosshairActive(true);
		}, 3);
	}
}

/**
 * @param {Client.Player} player
 * @param {Client.Character} entity
 */
function OnPlayerEntityLogout(player, entity) {

}

/**
 * @param {string} keyTag
 * @returns {int}
 */
function OnKeyDown(keyTag) {
	if (keyTag == "World_CameraMode") {
		if (CGame.CameraMode + 1 <= 2) {
			CGame.CameraMode++;
		} else {
			CGame.CameraMode = 0;
		}

		UpdateCameraState(CGame.CameraMode);
	}

	return 1;
}

/**
 * @param {Client.Character} character
 * @param {World.Prop} prop
 * @param {Vector} hitPos
 */
function OnCharacterPropAction(character, prop, hitPos) {
	if (character.Owner == Client.Player.Local) {
		Client.Camera.Punch(Misc.Clamp(prop.Damage * 0.005, 0.05, 0.5)); // + Random.Range(0.3, 0.6));
		Client.GUI.FocusCrosshair(0.2, 84, Random.Range(0.4, 0.7), Color(255, 0, 0));
	}
}

/**
 * @param {Client.Character} character
 * @param {World.Prop} prop
 * @param {bool} state
 */
function OnCharacterPropFocus(character, prop, state) {
	if (character.IsLocal) {
		if (state) {
			Client.GUI.SetCrosshair(9);
			Client.GUI.SetCrosshairScale(0.5);
			Client.GUI.SetCrosshairColor(Color(255, 255, 0));

			Client.Camera.FOV -= 40;
			Client.Camera.Offset = Vector(0.5, 1.6, 0);
			Client.Camera.Distance = 1;
			Client.Camera.TileShift = 8;
		} else {
			Client.GUI.SetCrosshair(0);
			Client.GUI.SetCrosshairScale(1);
			Client.GUI.SetCrosshairColor(Color(255, 255, 255));

			UpdateCameraState(CGame.CameraMode);
			Client.Camera.TileShift = 0;
		}
	}
}

/**
 * @param {Client.Character} character
 * @param {int} baseState
 */
function OnCharacterBaseState(character, baseState) {
	if (Client.Player.Local == null) return;
	if (character.Owner == Client.Player.Local) {
		if (baseState == 0 || baseState == 1) {
			Client.Camera.FOV = CGame.CameraFOV;
		}
		else if (baseState == 2) {
			Client.Camera.FOV = CGame.CameraFOV + 15;
		}
	}
}

/**
 * @param {string} cmd
 * @param {string} arg
 * @returns {int}
 */
function OnLocalCommand(cmd, arg) {
	if (cmd == "cexec") {
		try {
			Client.Core.Exec(arg);
			Client.Core.Message("CExec: " + arg.length);
		} catch (e) {
			Client.Core.Message("CExec Error: " + e);
		}
	}

	return 1;
}

/**
 * @param {Client.Player} player
 * @param {Client.Entity} entity
 */
function OnPlayerFocusEntityChange(player, entity) {
	Debug.LogError(player + "::" + entity);

	if (player.IsLocal) { // && player.IsObserver == false
		if (CGame.FocusEntityVehicle != null) {
			CGame.FocusEntityVehicle.Outline = false;
			CGame.FocusEntityVehicle = null;
		}

		if (entity && entity.IsVehicle && player.Entity.IsPassenger == false) {
			CGame.FocusEntityVehicle = entity;

			entity.Outline = true;
			Client.Core.BindActionKey("World_Use", "", () => {
				Client.Core.NetworkCMD("request_focus_use");
			}, true);
		} else {
			Client.Core.UnbindActionKey("World_Use");
		}
	}
}

/**
 * @param {Vector} point
 */
function OnPathTargetUpdate(point) {
	//Test
	if (Client.Character.Local.Vehicle) {
		Client.Character.Local.Vehicle.Pos = point;
	} else {
		Client.Character.Local.Pos = point;
	}
}